package org.totoro.patterns.create.abstracts.factory;

/**
 * 工厂模式是创建型模式，他封装了对象的创建过程，调用者使用具体的工厂方法根据参数就可以获取对应的对象。
 *
 * <pre>
 *     <img src="抽象工厂.png" />
 * </pre>
 *
 * <pre>
 *     如图BeanFactory接口提供了getBean方法，在AbstractBeanFactory中实现了该方法，
 *     经过层层继承，实现，最后DefaultListableBeanFactory实现了BeanDefinitionRegistry接口用来保存bean定义，
 *     继承了AbstractAutowireCapableBeanFactory用来支撑autowired。
 * </pre>
 *
 * <pre>
 * {@code
 *
 * @Test
 * public void testBeanFactoy() throws NamingException, SQLException, ParseException, IOException {
 *
 *     //创建Bean工厂
 *     DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
 *
 *     //给bean工厂添加bean定义,解析xml里面的bean放入bean工厂
 *     loadBeanDefinitions(bf);
 *
 *     //根据名字从bean工厂获取bean
 *     Hello hello = (Hello) bf.getBean("hello");
 *     hello.sayHello();
 *
 *     Hello2 hello2 = (Hello2) bf.getBean("hello2");
 *     hello2.sayHello();
 *
 *
 * }
 *
 * protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
 *     XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
 *
 *     String[] configLocations = new String[] { "beans2.xml" };
 *     if (configLocations != null) {
 *         beanDefinitionReader.loadBeanDefinitions(configLocations);
 *     }
 * }
 * }
 * </pre>
 *
 * <ul>
 * <li>不同条件下创建不同实例，用于统一管理bean</li>
 * <li>不同条件下调用不同工厂方法获取不同场景下的bean</li>
 * </ul>
 */
public abstract class Client {
    public static void main(String[] args) {
        Sender mailSender = new SendMailFactory().product();
        Sender smsSender = new SendSmsFactory().product();
        mailSender.send();
        smsSender.send();
    }
}
